//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
/***************************************************************/
#include "lh7a400_map.h"
#include "LH7A400_drivers.h"
#include "watertek_drivers.h"
#include "watertek_main.h"

// uart
void UartOpen( void );
UNS_32 UartGetChar( UNS_8 *charBuffer );
void UartClose( void );
void UartTest( void );
void Load_Main();

UNS_8 UART_rxBuf[RX_BUF_LEN];
UNS_8 UART_rxInPtr;
UNS_8 UART_rxOutPtr;

// touch panel
void TPTest( void );

extern UNS_32 penState;
extern UNS_32 penX;
extern UNS_32 penY;

// ethernet
void EthTest( void );

void NET_Init(void );
void NET_MainLoop(void );
void NET_Loop1ms(void );
void NET_Loop25ms(void );

extern UNS_32 Dm_waitForReset;

// lcd
extern UNS_16 lcdCurX;
extern UNS_16 lcdCurY;

void u_start(void)
{
    UNS_32 i, x, y;

    Lcd_PwOff();
    Lcd_LedOff();
    Dm_Close();

    InitInterrupt();

    Lcd_PwOn();
    Lcd_LedOn();
    Lcd_Init();

    Load_Main();
    while(1);

    TP_Init();
    TP_Calibrate();

    Lcd_FillScreen( WHITE );
    Lcd_DispIcon( ICON_X_0, ICON_Y_0, 0 );
    Lcd_DispIcon( ICON_X_1, ICON_Y_1, 1 );
    Lcd_DispIcon( ICON_X_2, ICON_Y_2, 2 );

    while (1) {
        if (penState) {
            penState = TP_PEN_UP;
            x = penX;
            y = penY;

            if ((x >= ICON_X_0) && (x <= ICON_X_0 + ICON_WIDTH) && (y >= ICON_Y_0) && (y <= ICON_Y_0 + ICON_HEIGHT)) {
                // uart test
                Lcd_InvIcon( ICON_X_0, ICON_Y_0 );
                while (penState) // wait pen up
                {
                    penState = TP_PEN_UP;
                    for( i=0; i<10000; i++ );
                }

                UartTest();
                Lcd_FillScreen( WHITE );
                Lcd_DispIcon( ICON_X_0, ICON_Y_0, 0 );
                Lcd_DispIcon( ICON_X_1, ICON_Y_1, 1 );
                Lcd_DispIcon( ICON_X_2, ICON_Y_2, 2 );
            }
            else if ((x >= ICON_X_1) && (x <= ICON_X_1 + ICON_WIDTH) && (y >= ICON_Y_1) && (y <= ICON_Y_1 + ICON_HEIGHT)) {                                           
                // touch panel test
                Lcd_InvIcon( ICON_X_1, ICON_Y_1 );
                while (penState) // wait pen up
                {
                    penState = TP_PEN_UP;
                    for( i=0; i<10000; i++ );
                }

                TPTest();
                Lcd_FillScreen( WHITE );
                Lcd_DispIcon( ICON_X_0, ICON_Y_0, 0 );
                Lcd_DispIcon( ICON_X_1, ICON_Y_1, 1 );
                Lcd_DispIcon( ICON_X_2, ICON_Y_2, 2 );
            }
            else if ((x >= ICON_X_2) && (x <= ICON_X_2 + ICON_WIDTH) && (y >= ICON_Y_2) && (y <= ICON_Y_2 + ICON_HEIGHT)) {
                // ethernet test
                Lcd_InvIcon( ICON_X_2, ICON_Y_2 );
                x = ICON_X_2;
                y = ICON_Y_2;
                while (penState) // wait pen up
                {
                    penState = TP_PEN_UP;
                    for( i=0; i<10000; i++ );
                }

                EthTest();
                Lcd_FillScreen( WHITE );
                Lcd_DispIcon( ICON_X_0, ICON_Y_0, 0 );
                Lcd_DispIcon( ICON_X_1, ICON_Y_1, 1 );
                Lcd_DispIcon( ICON_X_2, ICON_Y_2, 2 );
            }
        }
    }
}

/**********************************************************************************/
extern UNS_32 blRecvOver;
void EthTest(void)
{
    UNS_32 x, y;

    Lcd_FillScreen( WHITE );
    Lcd_DrawLine( 0, RETURN_Y, 240, RETURN_Y, BLACK );
    Lcd_DispStr(  40, RETURN_Y+8, BLUE, "ETH TEST RETURN ?" );
    lcdCurY = 0;

    timer_init( TIMER2 );                   // set timer2 periodic mode, 25ms
    timer_periodic( TIMER2 );
    timer_set_delay( TIMER2, 25000 );
    timer_int_enable( TIMER2 );
    timer_start( TIMER2 );

    NET_Init();
    while (1) {
        if (Dm_waitForReset) {             // error, reset dm9000
            Dm_FastReset();
            Dm_waitForReset = FALSE;
        }
        NET_MainLoop();
        if (blRecvOver) break;

        if (penState) {                   // return
            penState = TP_PEN_UP;
            x = penX;
            y = penY;

            if ((y > RETURN_Y) && (y < LCD_HEIGHT)) {
                break;
            }
        }
    }

    while(1);

    timer_int_disable( TIMER2 );
    timer_stop( TIMER2 );
    Dm_Close();
}

/**********************************************************************************/
void TPTest(void)
{
    UNS_32 preState, i, x, y, x0, y0;

    Lcd_FillScreen( WHITE );
    Lcd_DrawLine( 0, RETURN_Y, 240, RETURN_Y, BLACK );
    Lcd_DispStr(  48, RETURN_Y+8, BLUE, "TP TEST RETURN ?" );

    preState = TP_PEN_UP;
    while (1) {
        for( i=0; i<10000; i++ ) {
            ;
        }
        if (penState) {
            penState = TP_PEN_UP;
            x = penX;
            y = penY;

            if ((y > RETURN_Y) && (y < LCD_HEIGHT)) { // return
                break;
            }
            else {
                if (preState) {
                    Lcd_DrawLine( x0, y0, x, y, RED );
                    x0 = x;
                    y0 = y;
                }
                else {
                    preState = TP_PEN_DOWN;
                    x0 = x;
                    y0 = y;
                }
            }
        }
        else {
            preState = TP_PEN_UP;
        }
    }
}

/**********************************************************************************/

void UartTest(void)
{
    UNS_32 state, i, x, y, colour;
    UNS_8  uartTmp;

    colour = 0;
    Lcd_FillScreen( WHITE );
    Lcd_DrawLine( 0, RETURN_Y, 240, RETURN_Y, BLACK );
    Lcd_DispStr(  40, RETURN_Y+8, BLUE, "UART TEST RETURN ?" );

    UartOpen();

    lcdCurX = 0;
    lcdCurY = 0;
    while (1) {
        state = UartGetChar( &uartTmp );
        if (state == UART_OK) {                                                                   // receive a char
            LH7A400_uart_txb( UART2, uartTmp );                             // return the char
            Lcd_Printf( lcdCurX, lcdCurY, colour++, "%c", uartTmp );        // display the char
            if (lcdCurY > (RETURN_Y - CHAR_HEIGHT)) {
                Lcd_FillScreen( WHITE );
                Lcd_DrawLine( 0, RETURN_Y, 240, RETURN_Y, BLACK );
                Lcd_DispStr(  40, RETURN_Y+8, BLUE, "UART TEST RETURN ?" );
                lcdCurX = 0;
                lcdCurY = 0;
            }
        }

        if (penState) {                                                                   // return
            penState = TP_PEN_UP;
            x = penX;
            y = penY;

            if ((y > RETURN_Y) && (y < LCD_HEIGHT)) {
                break;
            }
        }
    }
    UartClose();
}

void UartOpen(void)
{
    UARTREGS uinit =
    {
        0,
        UART_LCR_STP1 | UART_LCR_PNONE | UART_LCR_WLEN8,
        UART_BCR_57600,
        UART_CONTROL_UART_ENABLE | UART_CONTROL_SIR_DISABLE,
        0,
        0,
        0,
        0
    };

    CPLD_SetPwrIO( RS232_PWR, 1 );              // max3244 power on
    LH7A400_uart_init ( UART2, &uinit );
    UART2->lcr  &= ~UART_LCR_FEN;               // disable fifo
    UART2->inte = UART_INTR_RI;                 // enable rx interrupt
    INTC->enableset |= INTC_UART2INTR;          // enable uart2 interrupt

    UART_rxOutPtr    = 0;
    UART_rxInPtr     = 0;
}

void UartClose(void)
{
    INTC->enableset &= ~INTC_UART2INTR;
    CPLD_SetPwrIO( RS232_PWR, 0 );
    UART2->control = ~UART_CONTROL_UART_ENABLE;
}

UNS_32 UartGetChar(UNS_8 *charBuffer)
{
    if (UART_rxInPtr == UART_rxOutPtr) {          // uart buffer empty
        *charBuffer = 0;
        return UART_RX_EMPTY;
    }
    else {                                        // uart buffer not empty
        *charBuffer = UART_rxBuf[UART_rxOutPtr++];
        return UART_OK;
    }
}

void Uart2ISR(void)
{
    UNS_32 state;

    state = UART2->intr;
    if (state & UART_INTR_RI) {                   // rx interrupt
        UART_rxBuf[UART_rxInPtr++] = UART2->data;       // put to buffer
    }
}
